package com.mask.juc;

import java.text.DecimalFormat;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 输出随机10000000相加结果 <br>
 * 多线程模拟其消耗时间 <br>
 * 线程数开辟多少合适
 * @author hx
 * @date 2021/10/10 6:10 下午
 */

public class MultiThreadContextSwitch {
    private static double[] nums = new double[1_0000_0000];
    private static Random r = new Random();
    private static DecimalFormat df = new DecimalFormat("0.00");
    static {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = r.nextDouble();
        }
    }

    private static void m1(){
        long start = System.currentTimeMillis();
        double result = 0.0;
        for (int i = 0; i < nums.length; i++) {
            result += nums[i];
        }
        long end = System.currentTimeMillis();
        System.out.println("m1花费时间"+(end -start)+"ms,"+"result:"+df.format(result));
    }

    //=================================================
    static double result = 0.0, result1 = 0.0, result2 = 0.00;
    private static void m2() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread t1 = new Thread(() ->{
            for (int i = 0; i < nums.length / 2; i++) {
                result1 += nums[i];
            } 
        });
        
        Thread t2 = new Thread(() ->{
            for (int i = nums.length / 2; i < nums.length; i++) {
                result2 += nums[i];
            } 
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        result = result1 + result2;
        long end = System.currentTimeMillis();

        System.out.println("m2花费时间"+(end -start)+"ms,"+"result:"+df.format(result));
    }
    //=========================================
    public static void m3() throws Exception{
        final int threadCount = 4;
        Thread[] threads = new Thread[threadCount];
        double[] results = new double[threadCount];
        final int segmentCount = nums.length /threadCount;
        CountDownLatch latch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            int m = i;
            threads[i] = new Thread(() ->{
                for (int j = m * segmentCount; j < (m + 1) * segmentCount && j < nums.length; j++) {
                    results[m] += nums[j];
                } 
            });

            latch.countDown();
        }
        double resultM3 = 0.0;
        long start = System.currentTimeMillis();
        for (Thread t : threads){
            t.start();
        }
        latch.await();
        for (int i = 0; i < results.length; i++) {
            resultM3 += results[i];
        }
        long end = System.currentTimeMillis();
        System.out.println("m3花费时间"+(end -start)+"ms,"+"result:"+df.format(result));
    }

    public static void main(String[] args) throws Exception {
        m1();
        m2();
        m3();
    }

}
